package com.hongpu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongpu.domain.HpProjectWorkPayListDetail;
import com.hongpu.dto.TotalContractAmountDto;
import com.hongpu.enums.ItHasBeenInvoicedEnum;
import com.hongpu.enums.YesOrNoEnum;
import com.hongpu.mapper.HpProjectWorkPayListDetailMapper;
import com.hongpu.service.HpProjectWorkPayListDetailService;
import com.hongpu.utils.ResultDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * @author Michael zhang
 * @description 针对表【hp_project_work_pay_list_detail(hp_project_work_pay_list表中支付数据的明细表)】的数据库操作Service实现
 * @createDate 2025-05-08 13:57:50
 */
@Service
public class HpProjectWorkPayListDetailServiceImpl extends ServiceImpl<HpProjectWorkPayListDetailMapper, HpProjectWorkPayListDetail>
        implements HpProjectWorkPayListDetailService {

    @Autowired
    HpProjectWorkPayListDetailMapper baseMapper;

    /**
     * 当支付数据的明细表中新增一条数据时，需要同时修改 hp_project_work_pay_list 中 paid 和 unpaid 的值
     *
     * @param hpProjectWorkPayListDetail
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(HpProjectWorkPayListDetail hpProjectWorkPayListDetail) {
        BigDecimal paid1 = hpProjectWorkPayListDetail.getPaid();
        if (paid1.compareTo(BigDecimal.ZERO) == 0) {
            throw new RuntimeException("请输入支付金额");
        }

        Integer detailInvoiceOrNot = hpProjectWorkPayListDetail.getInvoiceOrNot();
        if (detailInvoiceOrNot == null) {
            throw new RuntimeException("请选择是否需要开票");
        }

        try {
            boolean add = save(hpProjectWorkPayListDetail);
            if (add) {
                Long id = hpProjectWorkPayListDetail.getId();
                Long hpProjectWorkPayListId = hpProjectWorkPayListDetail.getHpProjectWorkPayListId();
                // 新增的支付金额
                BigDecimal paid = hpProjectWorkPayListDetail.getPaid() == null ? BigDecimal.ZERO : hpProjectWorkPayListDetail.getPaid();
                // 根据 hpProjectWorkPayListId 查询 hp_project_work_pay_list_detail 中已支付历史总额paidTotal
                BigDecimal paidTotal = baseMapper.selectPaidTotalByHpProjectWorkPayListIdExcludeId(hpProjectWorkPayListId, id) == null ? BigDecimal.ZERO : baseMapper.selectPaidTotalByHpProjectWorkPayListIdExcludeId(hpProjectWorkPayListId, id);
                // 根据 hpProjectWorkPayListId 修改  hp_project_work_pay_list 中 paid 的值, newPaid = paidTotal + paid
                BigDecimal newPaid = paidTotal.add(paid);
                baseMapper.updatePaidByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId(), newPaid);
                // 根据 hpProjectWorkPayListId 查询 hp_project_work_pay_list 中合同金额 contract_amount
                BigDecimal contractAmount = baseMapper.selectTotalContractAmountByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId()) == null ? BigDecimal.ZERO : baseMapper.selectTotalContractAmountByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId());
                // 根据 hpProjectWorkPayListId 修改  hp_project_work_pay_list 中 unpaid 的值 unpaid = contractAmount - newPaid
                BigDecimal unpaid = contractAmount.subtract(newPaid);
                baseMapper.updateUnpaidByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId(), unpaid);
                // 补充新增数据的开票信息：1、根据 hp_project_work_pay_list_id 查询一条开票信息，将该信息同步到新增的明细数据上。
                HpProjectWorkPayListDetail invoiceInfo = baseMapper.getInvoiceInfoByHpProjectWorkPayListId(hpProjectWorkPayListId);

                Integer invoiceOrNot = invoiceInfo.getInvoiceOrNot();
                if (YesOrNoEnum.YES.getValue().equals(invoiceOrNot)) {
                    // 处理需要开票的业务
                    invoiceInfo.setHpProjectWorkPayListId(hpProjectWorkPayListId);
                    this.updateInvoice(invoiceInfo);

                    // 修改是否已开票状态，根据invoiceInfo中的 itHasBeenInvoiced 修改 刚刚保存的 hpProjectWorkPayListDetail 中 itHasBeenInvoiced
                    // 参数：hpProjectWorkPayListDetail.getId()，invoiceInfo.getItHasBeenInvoiced()
                    baseMapper.updateItHasBeenInvoicedById(hpProjectWorkPayListDetail.getId(),invoiceInfo.getItHasBeenInvoiced());
                } else if (YesOrNoEnum.NO.getValue().equals(invoiceOrNot)) {
                    // 处理不需要开票的业务
                    this.updateNotInvoice(hpProjectWorkPayListId);
                } else {
                    throw new RuntimeException("系统无法判断新增的数据是否需要开票");
                }
            }

            // 判断是否需要更新合同金额
            String isUpdatetoTalContractAmount = hpProjectWorkPayListDetail.getIsUpdatetoTalContractAmount();
            if (String.valueOf(YesOrNoEnum.YES.getValue()).equals(isUpdatetoTalContractAmount)) {
                baseMapper.updateTotalContractAmount(hpProjectWorkPayListDetail.getHpProjectWorkPayListId());

                // 更新合同总金额
                TotalContractAmountDto totalContractAmount = baseMapper.getTotalContractAmount(hpProjectWorkPayListDetail.getHpProjectWorkPayListId());
                Long workPayId = totalContractAmount.getProjectWorkPayId();
                BigDecimal contractAmountAll = totalContractAmount.getContractAmountAll();
                baseMapper.updateWorkPayTotalContractAmount(contractAmountAll, workPayId);
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 当支付数据的明细表中删除一条数据时，需要同时修改 hp_project_work_pay_list 中 paid 和 unpaid 的值
     *
     * @param hpProjectWorkPayListDetail
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        try {
            HpProjectWorkPayListDetail hpProjectWorkPayListDetail = getById(id);
            if (hpProjectWorkPayListDetail == null) {
                return false;
            }
            boolean remove = removeById(hpProjectWorkPayListDetail);
            if (remove) {
                Long hpProjectWorkPayListId = hpProjectWorkPayListDetail.getHpProjectWorkPayListId();
                // 删除的支付金额
                BigDecimal paid = hpProjectWorkPayListDetail.getPaid() == null ? BigDecimal.ZERO : hpProjectWorkPayListDetail.getPaid();
                // 根据 hpProjectWorkPayListId 查询 hp_project_work_pay_list_detail 中已支付总额paidTotal
                BigDecimal paidTotal = baseMapper.selectPaidTotalByHpProjectWorkPayListId(hpProjectWorkPayListId) == null ? BigDecimal.ZERO : baseMapper.selectPaidTotalByHpProjectWorkPayListId(hpProjectWorkPayListId);
                // 根据 hpProjectWorkPayListId 修改  hp_project_work_pay_list 中 paid 的值, newPaid = paidTotal - paid
                BigDecimal newPaid = BigDecimal.ZERO;
                if (paidTotal.compareTo(BigDecimal.ZERO) == 0) {
                    newPaid = paidTotal;
                } else {
                  //  newPaid = paidTotal.subtract(paid);
                    newPaid = paidTotal;
                }

                baseMapper.updatePaidByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId(), newPaid);
                // 根据 hpProjectWorkPayListId 查询 hp_project_work_pay_list 中合同金额 contract_amount
                BigDecimal totalContractAmount = baseMapper.selectTotalContractAmountByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId()) == null ? BigDecimal.ZERO : baseMapper.selectTotalContractAmountByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId());
                // 根据 hpProjectWorkPayListId 修改  hp_project_work_pay_list 中 unpaid 的值 unpaid = totalContractAmount - newPaid
                BigDecimal unpaid = totalContractAmount.subtract(newPaid);
                baseMapper.updateUnpaidByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId(), unpaid);
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改支付数据的明细表，需要同时修改 hp_project_work_pay_list 中 paid 和 unpaid 的值
     *
     * @param hpProjectWorkPayListDetail
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDto update(HpProjectWorkPayListDetail hpProjectWorkPayListDetail) {

        hpProjectWorkPayListDetail.setHpProjectWorkPayListId(hpProjectWorkPayListDetail.getParentId());

        BigDecimal paid1 = hpProjectWorkPayListDetail.getPaid();
        if (paid1.compareTo(BigDecimal.ZERO) == 0) {
            ResultDto.fail("请输入支付金额");
        }

        try {
            Long hpProjectWorkPayListId = hpProjectWorkPayListDetail.getHpProjectWorkPayListId();
            Integer invoiceOrNot = hpProjectWorkPayListDetail.getInvoiceOrNot();
            if (YesOrNoEnum.YES.getValue().equals(invoiceOrNot)) {
                // hpProjectWorkPayListDetail 重新计算税额
                // 支付金额
                BigDecimal paid = hpProjectWorkPayListDetail.getPaid();

                // 税率
                BigDecimal invoiceTaxRate = hpProjectWorkPayListDetail.getInvoiceTaxRate();
                // 不含税金额 = hp_project_work_pay_list_detail表的支付金额 / (1+税率)
                BigDecimal amountBeforeTax = paid.divide(new BigDecimal(1).add(invoiceTaxRate), 2, RoundingMode.HALF_UP);
                //    税额= hp_project_work_pay_list_detail表的支付金额-不含税金额
                BigDecimal theAmountOfTaxToBePaid = paid.subtract(amountBeforeTax);

                hpProjectWorkPayListDetail.setAmountBeforeTax(amountBeforeTax);
                hpProjectWorkPayListDetail.setTheAmountOfTaxToBePaid(theAmountOfTaxToBePaid);

                baseMapper.updateOneHpProjectWorkPayListDetailData(hpProjectWorkPayListDetail);
                // 查询主数据的开票状态
                Integer itHasBeenInvoiced = baseMapper.selectItHasBeenInvoicedByHpProjectWorkPayListId(hpProjectWorkPayListId);
                if (ItHasBeenInvoicedEnum.OTHER.getValue().equals(itHasBeenInvoiced)) {
                    // 处理需要开票的业务
                    baseMapper.updateOneHpProjectWorkPayListDetailItHasBeenInvoiced(hpProjectWorkPayListDetail);
                }
            } else if (YesOrNoEnum.NO.getValue().equals(invoiceOrNot)) {
                baseMapper.updateOneHpProjectWorkPayListDetailData(hpProjectWorkPayListDetail);
                // 处理不需要开票的业务
                this.updateNotInvoice(hpProjectWorkPayListId);
            } else {
                return ResultDto.fail("系统无法判断新增的数据是否需要开票");
            }

            Long id = hpProjectWorkPayListDetail.getId();

            // 修改后的金额
            BigDecimal upPaid = hpProjectWorkPayListDetail.getPaid() == null ? BigDecimal.ZERO : hpProjectWorkPayListDetail.getPaid();
            // 根据 hpProjectWorkPayListId 查询 hp_project_work_pay_list_detail 中排除当前id对应的支付金额后其他相同hpProjectWorkPayListId已支付总额paidTotal
            BigDecimal paidTotal = baseMapper.selectPaidTotalByHpProjectWorkPayListIdExcludeId(hpProjectWorkPayListId, id) == null ? BigDecimal.ZERO : baseMapper.selectPaidTotalByHpProjectWorkPayListIdExcludeId(hpProjectWorkPayListId, id);
            // 根据 hpProjectWorkPayListId 修改  hp_project_work_pay_list 中 paid 的值, newPaid = paidTotal + upPaid
            BigDecimal newPaid = paidTotal.add(upPaid);
            baseMapper.updatePaidByHpProjectWorkPayListId(hpProjectWorkPayListId, newPaid);
            // 根据 hpProjectWorkPayListId 查询 hp_project_work_pay_list 中合同金额 contract_amount
            BigDecimal contractAmount = baseMapper.selectTotalContractAmountByHpProjectWorkPayListId(hpProjectWorkPayListId) == null ? BigDecimal.ZERO : baseMapper.selectTotalContractAmountByHpProjectWorkPayListId(hpProjectWorkPayListId);
            // 根据 hpProjectWorkPayListId 修改  hp_project_work_pay_list 中 unpaid 的值 unpaid = contractAmount - newPaid
            BigDecimal unpaid = contractAmount.subtract(newPaid);
            baseMapper.updateUnpaidByHpProjectWorkPayListId(hpProjectWorkPayListDetail.getHpProjectWorkPayListId(), unpaid);
            // 判断是否需要更新合同金额
            String isUpdatetoTalContractAmount = hpProjectWorkPayListDetail.getIsUpdatetoTalContractAmount();
            if (String.valueOf(YesOrNoEnum.YES.getValue()).equals(isUpdatetoTalContractAmount)) {
                // 更新合同金额
                baseMapper.updateTotalContractAmount(hpProjectWorkPayListDetail.getHpProjectWorkPayListId());
                // 更新合同总金额
                TotalContractAmountDto totalContractAmount = baseMapper.getTotalContractAmount(hpProjectWorkPayListDetail.getHpProjectWorkPayListId());
                Long workPayId = totalContractAmount.getProjectWorkPayId();
                BigDecimal contractAmountAll = totalContractAmount.getContractAmountAll();
                baseMapper.updateWorkPayTotalContractAmount(contractAmountAll, workPayId);
            }
            return ResultDto.ok();
        } catch (Exception e) {
            return ResultDto.fail(e.getLocalizedMessage());
        }
    }


    /**
     * 根据 hp_project_work_pay_list_id 查询 明细数据列表
     *
     * @param hpProjectWorkPayListId
     */
    @Override
    public List<HpProjectWorkPayListDetail> getByHpProjectWorkPayListId(Long hpProjectWorkPayListId) {
        QueryWrapper<HpProjectWorkPayListDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("hp_project_work_pay_list_id", hpProjectWorkPayListId);
        queryWrapper.orderByAsc("paid_time");
        List<HpProjectWorkPayListDetail> list = baseMapper.selectList(queryWrapper);
        return list;
    }

    /**
     * 将数据修改为不需要开票，且开票信息全置空
     *
     * @param payListDetailId
     * @param payListId
     */
    @Override
    public boolean updateNotInvoice(Long payListId) {
        return baseMapper.updateNotInvoice(payListId);
    }

    /**
     * 将数据修改为需要开票
     *
     * @param payListDetailId
     * @param payListId
     */
    @Override
    public boolean updateInvoice(HpProjectWorkPayListDetail hpProjectWorkPayListDetail) {
        return baseMapper.updateInvoice(hpProjectWorkPayListDetail);
    }

    @Override
    public boolean updateInvoiceInfoById(HpProjectWorkPayListDetail hpProjectWorkPayListDetail) {
        return baseMapper.updateInvoiceInfoById(hpProjectWorkPayListDetail);
    }

    /**
     * 更新 hp_project_work_pay_list_detail 表中 it_has_been_invoiced 字段为 itHasBeenInvoiced
     *
     * @param payListId
     * @param itHasBeenInvoiced
     */
    @Override
    public boolean updateItHasBeenInvoiced(Long hpProjectWorkPayListId, Integer itHasBeenInvoiced) {
        return baseMapper.updateItHasBeenInvoiced(hpProjectWorkPayListId, itHasBeenInvoiced);
    }

    /**
     * 根据 hp_project_work_pay_list_id 查询开票信息
     *
     * @param hpProjectWorkPayListId
     */
    @Override
    public HpProjectWorkPayListDetail getInvoiceInfoByHpProjectWorkPayListId(Long hpProjectWorkPayListId) {
        return baseMapper.getInvoiceInfoByHpProjectWorkPayListId(hpProjectWorkPayListId);
    }
}





